#ifndef CUTTER_H
#define CUTTER_H

#include <QDialog>
#include <QDir>
#include <QUrl>
#include <QMessageBox>
#include <QVideoWidget>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QStatusBar>
#include <QMimeData>
#include <QMenu>
#include <QFileInfo>
#include <QMediaPlayer>
#include <QFileDialog>
#include <QTimer>
#include <QStandardItemModel>
#include <QDateTime>
#include "ui_cutter.h"

// Macros.
#ifndef QT_NO_DEBUG
#define TRACE(a) (qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss.zzz ")+a)
#else
#define TRACE(a)
#endif
#define UNDEFINED_CURRENT_POSITION 0
#define UNDEFINED_A_POSITION -1000
#define UNDEFINED_B_POSITION -1000
#define UNDEFINED_TOTAL_TIME -1000
#define ONE_SECOND_IN_MILLIS 1000

class QMenu;
class QAction;

namespace Ui
{
class CutterClass;
}

class Cutter : public QDialog
{
    Q_OBJECT

    // File list context menu actions.
    enum
    {
        Load,
        MoveUp,
        MoveDown,
        Add,
        Remove,
        Clear
    };

    // Model columns
    enum ModelColumn
    {
        FileName,
        AbsoluteFilePath,
        CurrentPosition,
        APosition,
        BPosition,
        TotalLength
    };

public:
    Cutter(QWidget *parent = 0);
    ~Cutter();

    //! Check for video file in dragged item.
    void dragEnterEvent(QDragEnterEvent *event);

    //! Load video from dropped item.
    void dropEvent(QDropEvent *event);

    //! Load a video bu its url into the list.
    void loadListWithVideoUrl(const QUrl &url);

public slots:
    void reject();
    void stateChanged(QMediaPlayer::State newState);
    void mediaDurationChanged(qint64 newDuration);
    void tick(qint64 time);
    void loadVideo();
    void on_setCutA_clicked();
    void on_setCutB_clicked();
    void on_jumpToA_clicked();
    void on_jumpToB_clicked();
    void on_playPause_clicked();
    void on_saveScript_clicked();
    void on_jumpForward_clicked();
    void on_jumpBack_clicked();
    void deferredInit();
    void listDoubleClicked( const QModelIndex & index );
    void customContextMenuRequested( const QPoint & pos );
    void contextMenuLoad();
    void contextMenuMoveUp();
    void contextMenuMoveDown();
    void contextMenuRemove();
    void contextMenuClear();
    void contextMenuAdd();
    void sliderPressed() {
        seekPending = true;
    }
    void sliderReleased() {
        double newPosition = ui->seekSlider->value() * mediaPlayer->duration() / 100.0;
        TRACE(QString("Current: %1, new: %2").arg(mediaPlayer->position()).arg(newPosition));
        mediaPlayer->pause();
        mediaPlayer->setPosition((qint64)newPosition);
        seekPending = false;
    }

protected:
    /**
      Return the text in a line edit as a qint64.
      It is assumed that the value is the first
      field in widget's text. Space is used as the
      separator for fields.
      */
    qint64 lineEditTimeValue(QLineEdit *lineEdit);

    //! Capture close event to free video resources.
    void closeEvent(QCloseEvent *event);

    /**
      Set status box's text to a new string.
      */
    inline void msg(const QString &message)
    {
        ui->status->setText(message);
    }

    /**
      Set current video's data model row's one time variable to something.
      */
    void setDataTimeValue(Cutter::ModelColumn columnIndex, qint64 timeValue);

    /**
      Get data model row's one time variable for current video.
      */
    qint64 dataTimeValue(Cutter::ModelColumn columnIndex);

    /**
      Convert 64-bit video time in milliseconds into seconds.
      */
    inline double millisecondsIntoSeconds(qint64 milliseconds)
    {
        return milliseconds/1000.0;
    }

    /**
      Convert floating video time into 64-bit video time in milliseconds.
      */
    inline qint64 secondsIntoMilliseconds(double seconds)
    {
        return seconds*1000.0;
    }

    /**
      Create a displayable time string from input 64 bit video time.
      */
    inline QString printableMilliseconds(qint64 milliseconds)
    {
        return QString("%1 s").arg(millisecondsIntoSeconds(milliseconds));
    }

    //! Get a string list containing command lines to be saved as a shell script.
    QStringList createJoblist();

    //! Free resources used by video playback devices.
    void freeVideoResources();

private:
    Ui::CutterClass *ui;
    QStandardItemModel model;
    QMenu *listContextMenu;
    QList<QAction *>contextMenuActions;
    bool seekPending;
    QMediaPlayer *mediaPlayer;
    QScopedPointer<QMediaContent> mediaContent;
};

#endif // CUTTER_H
